const Minio = require("minio");
const stream = require("stream");

import { Message } from "element-ui";

const MINIOCLIENT = new Minio.Client({
  endPoint: "192.168.5.47",
  port: 9000,
  useSSL: false,
  accessKey: "admin",
  secretKey: "zhixin@123",
});

// 存储桶名称
const BucketName = "test";
// 文件存储位置
const SavePath = "mail";

function getClientInfo() {
  return MINIOCLIENT;
}

/**
 * @export 获取当前时间并格式化
 * @param {*} isDate Boolean 为真返回时分秒； 为"time"返回不带连接符的时分秒；为"fileDate"返回文件夹日期
 * @return {*} yyyy-MM-dd hh:mm:ss
 */
function getNowTime(isDate = false) {
  var now = new Date();
  var year = now.getFullYear(); //得到年份
  var month = now.getMonth(); //得到月份
  var date = now.getDate(); //得到日期
  var hh = now.getHours();
  var mm = now.getMinutes();
  var ss = now.getSeconds();
  var hour = " " + hh + ":" + mm + ":" + ss + ""; //默认时分秒 如果传给后台的格式为年月日时分秒，就需要加这个，如若不需要，此行可忽略
  var hours = hh + "" + mm + "" + ss + "-";
  month = month + 1;
  month = month.toString().padStart(2, "0");
  date = date.toString().padStart(2, "0");
  var defaultDate = `${year}-${month}-${date}${hour}`;
  if (isDate) {
    var defaultDate = `${year}-${month}-${date}`;
  }
  if (isDate == "time") {
    // 返回给文件前添加的时间
    var defaultDate = `${year}${month}${date}${hours}`;
  }
  if (isDate == "fileDate") {
    // 返回默认创建文件夹的时间
    var defaultDate = `${year}${month}${date}`;
  }
  return defaultDate;
}

/**
 *
 * @export base64转blob
 * @param {*} base64Data Object base64数据
 * @return {*} blob
 */
//base64转blob
function toBlob(base64Data) {
  let byteString = base64Data;
  if (base64Data.split(",")[0].indexOf("base64") >= 0) {
    byteString = window.atob(base64Data.split(",")[1]); // base64 解码
  } else {
    byteString = unescape(base64Data.split(",")[1]);
  }
  // 获取文件类型
  let mimeString = base64Data.split(";")[0].split(":")[1]; // mime类型

  // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
  // let arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
  // let uintArr = new Uint8Array(arrayBuffer) // 创建视图

  let uintArr = new Uint8Array(byteString.length); // 创建视图

  for (let i = 0; i < byteString.length; i++) {
    uintArr[i] = byteString.charCodeAt(i);
  }
  // 生成blob
  const blob = new Blob([uintArr], {
    type: mimeString,
  });
  // 使用 Blob 创建一个指向类型化数组的URL, URL.createObjectURL是new Blob文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
  return blob;
}

/**
 * 检查存储桶是否存在
 */
function checkBucketIsExists() {
  return new Promise((resolve, reject) => {
    MINIOCLIENT.bucketExists(BucketName, function (err) {
      if (!err) {
        resolve(true);
      } else {
        resolve(false);
      }
    });
  });
}

/**
 * @export 上传文件（stream流方法）
 * @param {*} fileObj Object 文件对象
 * @param {*} vm Object 调用该方法的页面的this
 * @return {*} null
 */
function uploadMinIo(fileObj) {
  return new Promise(async (resolve, reject) => {
    if (!fileObj) {
      Message({
        message: "文件类型错误！",
        type: "error",
      });
      return;
    }
    let file = fileObj;

    // 给文件名加上当前时间
    const fileName = getNowTime("time") + file.name;
    const fileDate = getNowTime("fileDate"); // 生成以日为分类的文件夹
    const mineType = file.type;
    const fileSize = file.size;
    //参数
    let metadata = {
      "content-type": mineType,
      "content-length": fileSize,
    };
    //判断储存桶是否存在
    if (!(await checkBucketIsExists())) {
      Message({
        message: "储存桶不存在！",
        type: "error",
      });
      return;
    }

    //准备上传
    let reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onloadend = function (e) {
      //读取完成触发，无论成功或失败
      const dataurl = e.target.result;
      //base64转blob
      const blob = toBlob(dataurl);
      //blob转arrayBuffer
      let reader2 = new FileReader();
      reader2.readAsArrayBuffer(blob);
      reader2.onload = function (ex) {
        //定义流
        let bufferStream = new stream.PassThrough();
        //将buffer写入

        bufferStream.end(Buffer.from(ex.target.result));
        //上传
        MINIOCLIENT.putObject(
          BucketName,
          fileName,
          bufferStream,
          fileSize,
          metadata,
          function (err, etag) {
            if (err == null) {
              // 为空则代表上传成功
              resolve({
                state: "ok",
                path: `http://192.168.5.47:9000/${BucketName}/${fileName}`,
                fileName,
                fileDate,
              });
            } else {
              reject({
                state: "fail",
              });
            }
          }
        );
      };
    };
  });
}

function downFile(filename, cb) {
  MINIOCLIENT.getObject(BucketName, filename, (err, dataStream) => {
    let size = 0;
    let totel = parseInt(dataStream && dataStream.headers["content-length"]);
    console.log("totel", totel);
    if (err) {
      return console.log(err);
    }
    dataStream.on("data", function (chunk) {
      size += chunk.length;
      let percentage = (size / totel) * 100;
      cb({ percentage });
    });
    dataStream.on("end", function () {
      cb({ percentage: 100 });
    });
    dataStream.on("error", function (err) {
      console.log(err);
    });
    cb();
  });
}

function getFileTempUrl(filename, cb) {
  return MINIOCLIENT.presignedUrl(
    "GET",
    BucketName,
    filename,
    24 * 60 * 60,
    (err, presignedUrl) => {
      downloadFileByUrl(presignedUrl, filename, cb);
    }
  );
}

function downloadFileByUrl(url, fileName, cb) {
  var xhr = new XMLHttpRequest();
  xhr.onprogress = (event) => {
    // 下载进度事件
    // loaded.innerText = event.loaded;
    // total.innerText = event.total;
    cb(event);
  };
  xhr.onload = (event) => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      // 下载完成之后
      var blob = new Blob([xhr.response]);
      var link = document.createElement("a"); // 创建a标签
      link.href = URL.createObjectURL(blob);
      link.download = fileName;
      link.click(); // js点击完成最终本地保存
    }
  };

  xhr.open("GET", url);
  xhr.send();
}

export { getClientInfo, uploadMinIo, downFile, getFileTempUrl };
